<?php

namespace App\Http\Controllers;

use App\Models\MchOrder;
use App\Models\Member;
use App\Models\MemberCoupon;
use App\Models\Red;
use App\Models\RedRecord;
use App\Models\Share;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Kuyuan\Phpwidget\Str;

/**
 * Class OpenRedController
 * @package App\Http\Controllers
 * Redis key值
 */
class OpenRedController extends Controller
{
    // 红包id
    private $_red_id = 0;
    // 分享id
    private $_share_id = '';
    // 当前用户id
    private $_member_id = 0;
    // 用户定位区域
    private $_area = '';
    // 红包信息
    private $Red = null;
    // 系统配置
    private $Setting = null;
    // 红包金额
    private $_money = 0;
    // 分享id信息
    private $Share = null;
    // 分享者奖励金额
    private $_award_money = 0;

    public function index(Request $request)
    {
        $this->_red_id = $request->red_id;
        $this->_area = $request->input('area','');
        $this->_share_id = $request->input('share_id','');
        $this->_member_id = auth('member')->id();
        $this->Setting = $this->getConfig();
        DB::beginTransaction();
        try{
            $this->Red = Red::lockForUpdate()->find($this->_red_id);
            // 1、红包验证
            $_check_red_result = $this->checkRed();
            if($_check_red_result['code'] != 200) {
                throw new \PDOException($_check_red_result['message'],$_check_red_result['code']);
            }

            // 2、发放卡券
            if($this->Red->send_coupon) {
                $this->sendCoupon();
            }

            // 3、计算红包金额
            $this->getMoney();

            // 3、助力红包，红包是否开启了助力红包，分享红包金额给分享者
            // 计算出实际的红包金额和分享者奖励红包金额
            if($this->Red->award && $this->_share_id) {
                $this->Share = Share::where("id",$this->_share_id)->first();
                if($this->Share &&  $this->Share->member_id != $this->_member_id && $this->Red->member_id != $this->_member_id) {
                    $this->shareAward();
                }
            }

            // 4、新增红包记录
            $RedRecord = new RedRecord();
            $RedRecord->member_id = $this->_member_id;
            $RedRecord->money = $this->_money;
            $RedRecord->red_id = $this->_red_id;
            $RedRecord->save();

            // 5、新增红包分享奖励记录
            if($this->_award_money !== 0) {
                $AwardRedRecord = new RedRecord();
                $AwardRedRecord->member_id = $this->Share->member_id;
                $AwardRedRecord->money = $this->_award_money;
                $AwardRedRecord->red_id = $this->_red_id;
                $AwardRedRecord->pid = $RedRecord->id;
                $AwardRedRecord->save();
            }

            // 6、是否操作用户余额
            $_handle_member_balance = true;

            // 7、是否操作分享奖励用户余额
            $_handle_award_member_balance = false;
            if($this->_award_money > 0) {
                $_handle_award_member_balance = true;
            }

            // 8、判断系统是否可以直接将红包金额到账用户微信钱包
            if($this->Setting->finance->deposit_check > 0) {
                // 8.1、判断红包金额是否小于审核金额
                if($this->directWechatWallet($this->_money)) {
                    // 微信商户转账到微信用户钱包
                    $_wechat_balance = $this->toBalance(
                        $this->_money,
                        'open',
                        $this->_red_id,
                        $this->_member_id
                    );
                    if($_wechat_balance['code'] == 200) {
                        $_handle_member_balance = false;
                        $RedRecord->go_to = 2;
                        $RedRecord->save();
                    }
                }
                // 8.2、判断分享红包奖励金额是否小于审核金额
                if($this->_award_money > 0 && $this->directWechatWallet($this->_award_money)) {
                    $_wechat_award_balance = $this->toBalance(
                        $this->_award_money,
                        'open-award',
                        $this->_red_id,
                        $this->Share->member_id,
                        "用户<".Member::where("id",$this->Share->member_id)->value('nickname').">帮您开到的红包"
                    );
                    if($_wechat_award_balance['code'] == 200) {
                        $_handle_award_member_balance = false;
                        $AwardRedRecord->go_to = 2;
                        $AwardRedRecord->save();
                    }
                }
            }

            // 9、操作用户余额
            if($_handle_member_balance) {
                Member::where("id",$this->_member_id)->increment('red_balance',$this->_money);
            }

            // 10、操作分享奖励用户金额
            if($_handle_award_member_balance) {
                Member::where("id",$this->Share->member_id)->increment('red_balance',$this->_award_money);
            }

            // 11、新增红包开启数量
            Red::where("id",$this->_red_id)->increment('numbered');
            DB::commit();
            // end:成功返回，红包信息
            $_result_data = array(
                "money"=>Str::format_money($this->_money)
            );
            if($this->Red->send_coupon) {
                $_result_data["coupon_id"] = $this->Red->coupon;
            }
            return response(['data'=>$_result_data]);
        } catch (\PDOException $e) {
            DB::rollBack();
            return response(['message'=>$e->getMessage()],$e->getCode());
        }
    }

    /**
     * 验证红包
     */
    private function checkRed()
    {
        // 1、验证红包是否存在
        if(!$this->Red) {
            return array('code'=>402,'message'=>'红包不存在');
        }

        // 2、红包限制区域验证
        if($this->Red->area_type != 0) {
            if(mb_strpos($this->_area,$this->Red->area) === false) {
                return array('code'=>402,'message'=>"仅支持".$this->Red->area."的用户开红包");
            }
        }

        // 3、红包状态验证
        if($this->Red->status != 2) {
            switch ($this->Red->status) {
                case '4':
                    return array('code'=>402,'message'=>"红包已停止发放");
                    break;
                case '1':
                    return array('code'=>402,'message'=>"非法操作[1]");
                    break;
                default:
                    return array('code'=>402,'message'=>"未知错误[1]");
            }
        }

        // 4、红包开始结束时间验证
        if($this->Red->time_type == 2) {
            $_timestamp = time();
            if($_timestamp < $this->Red->start_time) {
                return array("code"=>402,"message"=>"红包正在准备中");
            } else if($_timestamp > $this->Red->end_time) {
                return array("code"=>402,"message"=>"红包已过期");
            }
        }

        // 5、验证当前用户是否开启过红包
        if(
            // 红包开启记录
            RedRecord::where("red_id",$this->_red_id)
                ->where('member_id',$this->_member_id)
                ->where('pid',0)->exists()
            ||
            // 商户资金记录是否交易成功
            MchOrder::where("source","open")
                ->where("source_id",$this->_red_id)
                ->where("member_id",$this->_member_id)->where("status",2)
                ->exists()
        ) {
            return array("code"=>402,"message"=>"您已开过此红包了");
        }

        // 6、验证红包数量
        if($this->Red->numbered >= $this->Red->number) {
            return array("code"=>402,"message"=>"您来晚了，红包已经发完");
        }

        return array('code'=>200);
    }

    /**
     * 发放卡券
     */
    private function sendCoupon()
    {
        MemberCoupon::create([
            'member_id' => $this->_member_id,
            'red_id' => $this->_red_id,
            'coupon_id' =>$this->Red->coupon,
            'indate' => ['coupon_id'=>$this->Red->coupon]
        ]);
    }

    /**
     * 生成红包金额
     */
    private function getMoney()
    {
        if($this->Red->type == 1) {
            $this->_money = $this->Red->money;
        } else {
            $this->_money = $this->randomMoney();
        }
    }



    /**
     * 获取手气红包随机金额
     */
    private function randomMoney()
    {
        // 1、获取手气红包的剩余金额
        $_surplus_money = $this->surplus();
        // 2、红包剩余数量
        $_surplus_number = $this->Red->number - $this->Red->numbered;

        // 3、判断是不是最后一个红包
        if($_surplus_number == 1) {
            // 是最后一个红包
            // 3.1、如果是最后一个将剩余红包金额都返回
            $_money = $_surplus_money;
        } else {
            // 3.0、否则算出一个随机金额
            // 3.1、红包剩余总金额/红包剩余数量,算出红包随机金额最大值
            $_average = $_surplus_money / $_surplus_number;
            // 3.3、红包随机金额最小值
            $_min = 1;
            // 3.4、随机出最小值到最大值的随机金额
            $_money = mt_rand($_min,$_average);
        }
        return $_money;
    }

    /**
     * 计算出手气红包的剩余总金额
     */
    private function surplus()
    {
        $_already_money = RedRecord::where("red_id", $this->_red_id)
            ->sum("money");
        $_total_money = Red::where("id", $this->_red_id)
            ->value("money");
        return $_total_money - $_already_money;
    }

    /**
     * 分享奖励红包
     */
    private function shareAward()
    {
        if($this->Setting->share_ratio) {
            $_share_ratio = round($this->Setting->share_ratio / 100,2);
            $this->_award_money = $this->_money * $_share_ratio;
            if($this->_award_money >= 1) {
                $this->_money -= $this->_award_money;
            } else if(($this->_award_money < 1) && ($this->_money - 1 >= 1)){
                $this->_money -= 1;
                $this->_award_money = 1;
            }
        }
    }

    /**
     * 判断金额是否直接到用户微信钱包
     * @param int $_money 金额
     * @return bool
     */
    private function directWechatWallet($_money)
    {
        if($_money >= $this->Setting->finance->deposit_check) {
            return false;
        }
        if($_money < $this->Setting->finance->low_deposit) {
            return false;
        }
        return true;
    }
}
